package com.phpxiu.app.view;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Message;
import android.support.annotation.Nullable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.alipay.sdk.app.PayTask;
import com.paypal.android.sdk.payments.PayPalConfiguration;
import com.paypal.android.sdk.payments.PayPalPayment;
import com.paypal.android.sdk.payments.PayPalService;
import com.paypal.android.sdk.payments.PaymentActivity;
import com.paypal.android.sdk.payments.PaymentConfirmation;
import com.phpxiu.app.adapter.UserAccountProductListAdapter;
import com.phpxiu.app.config.HttpConfig;
import com.phpxiu.app.kkylive.KKYApp;
import com.phpxiu.app.kkylive.R;
import com.phpxiu.app.model.MySelfInfo;
import com.phpxiu.app.model.event.OnUpdateBalance;
import com.phpxiu.app.model.event.WeiXinPayEvent;
import com.phpxiu.app.model.list.UserAccountProductContent;
import com.phpxiu.app.model.response.AliOrderModel;
import com.phpxiu.app.model.response.UserAccountListMode;
import com.phpxiu.app.model.response.WXOrderModel;
import com.phpxiu.app.okhttp.OKHttp;
import com.phpxiu.app.okhttp.handler.OKHttpUIHandler;
import com.phpxiu.app.okhttp.param.OKHttpParam;
import com.phpxiu.app.utils.KKYUtil;
import com.phpxiu.app.view.custom.VerticalImageSpan;
import com.phpxiu.app.view.custom.WindowLayout;
import com.tencent.bugly.imsdk.crashreport.CrashReport;
import com.tencent.mm.sdk.modelpay.PayReq;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.WXAPIFactory;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import de.greenrobot.event.EventBus;
import de.greenrobot.event.Subscribe;

/**
 * 用户账户
 * Created by WuJinZhou on 2016/6/4.
 */
public class UserAccount extends UIBase implements View.OnClickListener{
    public final static String TAG="UserAccount";
    public final static String ROOM_PAY_RECHARGE_ACTION="room_pay_recharge_action";
    public final static String EXTRA_PARAM_BALANCE_KEY="extra_param_balance_key";
    private final static String PP_CLIENT_ID="AarbaDODceid0wK6Cz0Q1Qzmo_BPZ2OlewjSmVbOx4Gy8CjHdIFvVAsjSFMEEkiEs3R55wDRGHlD46CM";
    private final static int REQUEST_CODE_PP_PAY=0x88;
    private final static int HANDLER_MSG_SHOW_ALI_RESULT=0x1;
    private final static int HANDLER_MSG_SHOW_WX_RESULT=0x2;
    public final static int PAY_MODE_ALI=0x1;
    public final static int PAY_MODE_WX=0x2;
    public final static int PAY_MODE_PP=0x3;
    private WindowLayout mainView;
    private View headView;
    private TextView headTitleView;
    private SpannableStringBuilder titleTxt=new SpannableStringBuilder();
    private VerticalImageSpan icon;
    private int mainColor;
    private long balance=0;
    private ListView mListView;
    private List<UserAccountProductContent>aliProducts=new ArrayList<UserAccountProductContent>();//支付宝商品列表
    private List<UserAccountProductContent>wxProducts=new ArrayList<UserAccountProductContent>();//微信商品列表
    private List<UserAccountProductContent>PProducts=new ArrayList<>();//PayPal商品列表
    private List<UserAccountProductContent>productContents=new ArrayList<UserAccountProductContent>();
    private UserAccountProductListAdapter mAdapter;
    private boolean isCallPaying=false;//支付处理中
    private int currentPayMode=PAY_MODE_ALI;//默认支付宝支付
    private RelativeLayout tabAli,tabWX,tabP;
    private ImageView aliIcon,wxIcon,ppIcon;
    private TextView aliModeView,wxModeView,ppModeView;
    private long payingProductValue=0;//正在支付的商品虚拟值
    private static IWXAPI iwxapi=KKYApp.getInstance().mWeiXinAPI;

    private final static  String CONFIG_ENVIRONMENT = PayPalConfiguration.ENVIRONMENT_SANDBOX;//沙箱模式
    private final static PayPalConfiguration PPConfig = new PayPalConfiguration()
            .environment(CONFIG_ENVIRONMENT)
            .clientId(PP_CLIENT_ID);
    private String ppOrderTitlePrefix="";

    private String action=null;//充值标识，扣费充值请求时，此值不为空
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        action=getIntent().getStringExtra(ROOM_PAY_RECHARGE_ACTION);//如果为空则不是扣费充值
        startPPSever();
        EventBus.getDefault().register(this);
        currentPayMode=PAY_MODE_ALI;
        balance=getIntent().getLongExtra(EXTRA_PARAM_BALANCE_KEY,0);
        setContentView(R.layout.user_account);
        findViewById(R.id.top_bar_back_btn).setOnClickListener(this);
        ppOrderTitlePrefix=getString(R.string.ui_paypal_order);
        init();
    }

    /**
     * 启动PayPal支付服务
     */
    final private void startPPSever(){
        Intent intent = new Intent(this, PayPalService.class);
        intent.putExtra(PayPalService.EXTRA_PAYPAL_CONFIGURATION, PPConfig);
        startService(intent);
    }

    /**
     * 初始化
     */
    private void init(){
        mainView=(WindowLayout)findViewById(R.id.account_root_view);
        headView= LayoutInflater.from(this).inflate(R.layout.user_account_product_list_head_view,null);
        headView.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        headTitleView=(TextView)headView.findViewById(R.id.head_title);
        tabAli=(RelativeLayout)headView.findViewById(R.id.tab_alipay);
        tabAli.setSelected(true);
        aliIcon=(ImageView)headView.findViewById(R.id.alipay_icon);
        //aliIcon.setImageResource();
        aliModeView=(TextView)headView.findViewById(R.id.alipay_title);
        aliModeView.setSelected(true);
        tabAli.setOnClickListener(this);

        tabWX=(RelativeLayout)headView.findViewById(R.id.tab_weChat);
        wxIcon=(ImageView)headView.findViewById(R.id.weChat_icon);
        //wxIcon.setImageResource();
        wxModeView=(TextView)headView.findViewById(R.id.weChat_title);
        tabWX.setOnClickListener(this);

        tabP=(RelativeLayout)headView.findViewById(R.id.tab_pp);
        ppIcon=(ImageView)headView.findViewById(R.id.pp_icon);
        //wxIcon.setImageResource();
        ppModeView=(TextView)headView.findViewById(R.id.pp_title);
        tabP.setOnClickListener(this);

        icon=new VerticalImageSpan(this, R.mipmap.diamond_icon);
        mainColor=getResources().getColor(R.color.main_color);
        refreshBalance();
        mListView=(ListView)findViewById(R.id.account_product_list_view);
        mListView.setDivider(null);
        mListView.addHeaderView(headView);
        mAdapter=new UserAccountProductListAdapter(this,productContents);
        mListView.setAdapter(mAdapter);
        request();
    }

    private void refreshBalance(){
        String balanceLabel=getString(R.string.ui_account_balance);
        String balanceStr=balance+"";
        titleTxt.clear();
        titleTxt.append(balanceLabel).append("icon ").append(balanceStr);
        titleTxt.setSpan(icon,balanceLabel.length(),balanceLabel.length()+5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        titleTxt.setSpan(new ForegroundColorSpan(mainColor),balanceLabel.length()+5,titleTxt.length(),Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        //titleTxt.setSpan(new StyleSpan(Typeface.BOLD),balanceLabel.length()+5,titleTxt.length(),Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        headTitleView.setText(titleTxt);
    }

    /**
     * 请求初始化数据
     */
    private void request(){
        OKHttpParam param=OKHttpParam.builder(false);
        OKHttp.post(HttpConfig.API_ACCOUNT_GOODS, param.jsonParam(), TAG, new OKHttpUIHandler(UserAccountListMode.class) {
            @Override
            public void onSuccess(Object model) {
                UserAccountListMode m = (UserAccountListMode) model;
                KKYUtil.log("获取商品列表：" + m.getResponseStr());
                try {
                    productContents.clear();
                    aliProducts.clear();
                    aliProducts.addAll(m.getData().getAlipay());
                    wxProducts.addAll(m.getData().getWeixin());
                    productContents.addAll(aliProducts);
                    PProducts.addAll(m.getData().getPaypal());
                    mAdapter.notifyDataSetChanged();
                } catch (NullPointerException e) {
                    CrashReport.postCatchedException(e);
                }
            }

            @Override
            public void onErr(String errMsg) {
                mainView.showTopMsg("Loaded failed：" + errMsg);
            }
        });
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.top_bar_back_btn:
                onBackPressed();
                break;
            case R.id.tab_alipay:
                mAdapter.setUSD(false);
                tabWX.setSelected(false);
                wxIcon.setImageResource(R.mipmap.wx_mode_normal_icon);
                wxModeView.setSelected(false);

                tabP.setSelected(false);
                ppIcon.setImageResource(R.mipmap.pp_mode_normal_icon);
                ppModeView.setSelected(false);

                tabAli.setSelected(true);
                aliIcon.setImageResource(R.mipmap.alipay_mode_selected_icon);
                aliModeView.setSelected(true);
                currentPayMode=PAY_MODE_ALI;
                productContents.clear();
                productContents.addAll(aliProducts);
                mAdapter.notifyDataSetChanged();
                break;
            case R.id.tab_weChat:
                mAdapter.setUSD(false);
                tabAli.setSelected(false);
                aliIcon.setImageResource(R.mipmap.alipay_mode_normal_icon);
                aliModeView.setSelected(false);

                tabP.setSelected(false);
                ppIcon.setImageResource(R.mipmap.pp_mode_normal_icon);
                ppModeView.setSelected(false);

                tabWX.setSelected(true);
                wxIcon.setImageResource(R.mipmap.wx_mode_selected_icon);
                wxModeView.setSelected(true);
                currentPayMode=PAY_MODE_WX;
                productContents.clear();
                productContents.addAll(wxProducts);
                mAdapter.notifyDataSetChanged();
                break;
            case R.id.tab_pp:
                mAdapter.setUSD(true);
                tabAli.setSelected(false);
                aliIcon.setImageResource(R.mipmap.alipay_mode_normal_icon);
                aliModeView.setSelected(false);
                tabWX.setSelected(false);
                wxIcon.setImageResource(R.mipmap.wx_mode_normal_icon);
                wxModeView.setSelected(false);

                tabP.setSelected(true);
                ppIcon.setImageResource(R.mipmap.pp_mode_selected_icon);
                ppModeView.setSelected(true);
                currentPayMode=PAY_MODE_PP;
                productContents.clear();
                productContents.addAll(PProducts);
                mAdapter.notifyDataSetChanged();
                break;
            default:
                break;
        }
    }

    /**
     * 下单购买
     */
    public void onOrder(UserAccountProductContent productContent){
        KKYUtil.log("订单：" + productContent.getName() + "@" + productContent.getCoin() + "#" + productContent.getMoney());
        if(isCallPaying){
            return;
        }
        //如果是PayPay方式支付，直接支付
        if(currentPayMode==PAY_MODE_PP){
            try {
                payingProductValue=Long.parseLong(productContent.getCoin());
            }catch (NumberFormatException e){
                CrashReport.postCatchedException(e);
            }
            payByPayPal(productContent);
            isCallPaying=true;
            return;
        }

        OKHttpParam param=OKHttpParam.builder(false);
        param.put("goodid",productContent.getId());
        isCallPaying=true;
        if(currentPayMode==PAY_MODE_ALI){
            orderByAli(param.jsonParam(),productContent);
        }
        if(currentPayMode==PAY_MODE_WX){
            try {
                payingProductValue=Long.parseLong(productContent.getCoin());
            }catch (NumberFormatException e){
                CrashReport.postCatchedException(e);
            }
            orderByWX(param.jsonParam());
        }
    }

    /**
     * 创建PayPal订单，调用PayPal支付
     * @param productContent
     */
    public void payByPayPal(UserAccountProductContent productContent){
        BigDecimal cost=new BigDecimal(productContent.getMoney());
        cost.setScale(2,BigDecimal.ROUND_HALF_UP);
        String title=ppOrderTitlePrefix+"("+productContent.getCoin()+")";
        PayPalPayment order=new PayPalPayment(cost,"USD",title,
                PayPalPayment.PAYMENT_INTENT_SALE);
        String uid=MySelfInfo.getInstance().getId();
        String custom="{\"uid\":\""+uid+"\",\"goodid\":\""+productContent.getId()+"\"}";
        KKYUtil.log("PayPal custom=="+custom);
        order.custom(custom);
        Intent payWithPP = new Intent(this, PaymentActivity.class);
        // send the same configuration for restart resiliency
        payWithPP.putExtra(PayPalService.EXTRA_PAYPAL_CONFIGURATION, PPConfig);
        payWithPP.putExtra(PayPalService.EXTRA_PAYPAL_CONFIGURATION, PPConfig);
        payWithPP.putExtra(PaymentActivity.EXTRA_PAYMENT,order);
        startActivityForResult(payWithPP, REQUEST_CODE_PP_PAY);
    }

    /**
     * 支付宝订单
     */
    private void orderByAli(String param,final UserAccountProductContent productContent){
        OKHttp.post(HttpConfig.API_GET_PAY_ORDER,param,TAG,new OKHttpUIHandler(AliOrderModel.class) {
            @Override
            public void onSuccess(Object model) {
                AliOrderModel m=(AliOrderModel)model;
                KKYUtil.log("获取订单结果："+m.getResponseStr());
                try {
                    payOrder(m.getData().getOrder(),productContent.getCoin());
                }catch (NullPointerException e){
                    CrashReport.postCatchedException(e);
                }
            }

            @Override
            public void onErr(String errMsg) {
                isCallPaying=false;
                mainView.showTopMsg(errMsg);
            }
        });
    }

    /**
     * 微信订单
     */
    private void orderByWX(String param){
        OKHttp.post(HttpConfig.API_GET_WX_ORDER,param,TAG,new OKHttpUIHandler(WXOrderModel.class) {
            @Override
            public void onSuccess(Object model) {
                WXOrderModel m=(WXOrderModel)model;
                KKYUtil.log("获取订单结果："+m.getResponseStr());
                if(iwxapi==null){
                    iwxapi = WXAPIFactory.createWXAPI(getApplicationContext(), BaseLogin.WX_APP_ID, true);
                    iwxapi.registerApp(BaseLogin.WX_APP_ID);
                }
                try {
                    PayReq request = new PayReq();
                    request.appId =m.getData().getAppid();
                    request.partnerId = m.getData().getPartnerid();
                    request.prepayId=m.getData().getPrepayid();
                    request.packageValue = "Sign=WXPay";
                    request.nonceStr=m.getData().getNoncestr();
                    request.timeStamp= m.getData().getTimestamp();
                    request.sign= m.getData().getSign();
                    iwxapi.sendReq(request);
                }catch (Exception e){
                    isCallPaying=false;
                    payingProductValue=0;
                    mainView.showTopMsg(getString(R.string.account_pay_failed));
                    CrashReport.postCatchedException(e);
                }

            }

            @Override
            public void onErr(String errMsg) {
                isCallPaying=false;
                mainView.showTopMsg(errMsg);
            }
        });
    }

    /**
     * 请求支付
     */
    public void payOrder(final String order,final String coin){
        if(order==null){
            isCallPaying=false;
            return;
        }
        if(isFinishing()) {
            isCallPaying=false;
            return;
        }else{
            if (order == null || order.equals("")) {
                mainView.showTopMsg(getString(R.string.account_pay_failed));
                isCallPaying=false;
                return;
            }
        }
        // 获取到购买的信息后 开启购买支付的线程
        Runnable payRunnable = new Runnable() {
            @Override
            public void run() {
                try {
                    // 构造PayTask 对象
                    PayTask alipay = new PayTask(UserAccount.this);
                    // 调用支付接口，获取支付结果
                    Map<String,String> result = alipay.payV2(order,true);
                    Message msg =handler.obtainMessage();
                    msg.what =HANDLER_MSG_SHOW_ALI_RESULT;
                    msg.obj = new PayInfo(coin,result);
                    handler.sendMessage(msg);
                }catch (NullPointerException e){
                    isCallPaying=false;
                    mainView.showTopMsg(getString(R.string.account_pay_failed));
                    CrashReport.postCatchedException(e);
                }

            }
        };
        // 必须异步调用
        Thread payThread = new Thread(payRunnable);
        payThread.start();
    }

    @Override
    public void handleMsg(Message msg) {
        switch (msg.what){
            case HANDLER_MSG_SHOW_ALI_RESULT:
                isCallPaying=false;
                showResult(msg);
                break;
            case HANDLER_MSG_SHOW_WX_RESULT:
                isCallPaying=false;
                if(msg.obj!=null){
                    mainView.showTopMsg(msg.obj.toString());
                }
                break;
            default:
                break;
        }
    }

    /**
     * 显示处理充值结果
     */
    public void showResult(Message msg){
        PayInfo payInfo=(PayInfo)msg.obj;
        // 支付宝返回此次支付结果及加签，建议对支付宝签名信息拿签约时支付宝提供的公钥做验签
        String resultStatus = payInfo.getResult().get("resultStatus");
        KKYUtil.log("支付支付结果："+resultStatus);
        // 判断resultStatus 为“9000”则代表支付成功，具体状态码代表含义可参考接口文档
        if (TextUtils.equals(resultStatus, "9000")) {
            long money=Long.parseLong(payInfo.getCoin());
            balance=balance+money;
            MySelfInfo.getInstance().updateMoney(UserAccount.this,true,money);
            refreshBalance();
            //更新余额
            EventBus.getDefault().postSticky(new OnUpdateBalance(balance));
            mainView.showTopMsg(getString(R.string.account_pay_success));
            onRechargeSuccess();
        } else {
            // 判断resultStatus 为非“9000”则代表可能支付失败
            // “8000”代表支付结果因为支付渠道原因或者系统原因还在等待支付结果确认，最终交易是否成功以服务端异步通知为准（小概率状态）
            if (TextUtils.equals(resultStatus, "8000")) {
                KKYUtil.log(TAG,"支付结果确认中...");
            }else if(TextUtils.equals(resultStatus, "6001")){
                KKYUtil.log(TAG,"已取消支付");
                mainView.showTopMsg(getString(R.string.account_pay_cancel));
            } else {
                // 其他值就可以判断为支付失败，包括用户主动取消支付，或者系统返回的错误
                mainView.showTopMsg(getString(R.string.account_pay_failed)+resultStatus);
            }
        }
    }

    /**
     * 充值成功
     */
    final private void onRechargeSuccess(){
        if(ROOM_PAY_RECHARGE_ACTION.equals(action)){
            setResult(RESULT_OK);
        }
    }

    static class PayInfo{
        private String coin;
        private Map<String,String> result;

        PayInfo(String coin, Map<String,String> result) {
            this.coin = coin;
            this.result = result;
        }

        public String getCoin() {
            return coin;
        }

        public void setCoin(String coin) {
            this.coin = coin;
        }

        public Map<String, String> getResult() {
            return result;
        }

        public void setResult(Map<String, String> result) {
            this.result = result;
        }
    }

    /**
     * 微信支付结果
     */
    @Subscribe
    public void onWeiXinPayFinish(WeiXinPayEvent event){
        String msg=null;
        switch (event.getStateCode()){
            case WeiXinPayEvent.PAY_SUCCESS:
                balance=balance+payingProductValue;
                MySelfInfo.getInstance().updateMoney(UserAccount.this,true,payingProductValue);
                refreshBalance();
                //更新余额
                EventBus.getDefault().postSticky(new OnUpdateBalance(balance));
                msg=getString(R.string.account_pay_success);
                onRechargeSuccess();
                break;
            case WeiXinPayEvent.PAY_CANCEL:
                msg=getString(R.string.account_pay_cancel);
                break;
            case WeiXinPayEvent.PAY_ERR:
                msg=getString(R.string.account_pay_failed);
                break;
        }
        if(msg!=null){
            Message message=handler.obtainMessage();
            message.what=HANDLER_MSG_SHOW_WX_RESULT;
            message.obj=msg;
            handler.sendMessage(message);
        }
        payingProductValue=0;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_CODE_PP_PAY) {
            isCallPaying=false;
            if (resultCode == Activity.RESULT_OK) {
                PaymentConfirmation confirm =data.getParcelableExtra(PaymentActivity.EXTRA_RESULT_CONFIRMATION);
                if (confirm != null) {
                    String state=confirm.getProofOfPayment().getState();
                    if("approved".equals(state)){
                        //PayPal支付成功
                        balance=balance+payingProductValue;
                        MySelfInfo.getInstance().updateMoney(UserAccount.this,true,payingProductValue);
                        refreshBalance();
                        //更新余额
                        EventBus.getDefault().postSticky(new OnUpdateBalance(balance));
                        onRechargeSuccess();
                        mainView.showTopMsg(getString(R.string.account_pay_success));
                        return;
                    }
                }
                mainView.showTopMsg(getString(R.string.account_pay_failed));
            } else if (resultCode == Activity.RESULT_CANCELED) {
                mainView.showTopMsg(getString(R.string.account_pay_cancel));
            } else if (resultCode == PaymentActivity.RESULT_EXTRAS_INVALID) {
                mainView.showTopMsg(getString(R.string.account_pay_failed));
                Log.i(TAG,"An invalid Payment or PayPalConfiguration was submitted. Please see the docs.");
            }
        }else{
            super.onActivityResult(requestCode,resultCode,data);
        }
    }

    @Override
    public void finish() {
        OKHttp.cancelRequest(TAG);
        super.finish();
    }

    @Override
    protected void onDestroy() {
        stopService(new Intent(this, PayPalService.class));
        EventBus.getDefault().unregister(this);
        super.onDestroy();
    }
}
